package com.blm.service.impl;

import com.blm.common.constants.CacheConstant;
import com.blm.common.constants.ExceptionConstant;
import com.blm.entity.Review;
import com.blm.entity.Store;
import com.blm.entity.User;
import com.blm.exception.CommonException;
import com.blm.repository.ReviewRepository;
import com.blm.service.MerchantReviewService;
import com.blm.service.StoreService;
import com.blm.service.UserService;
import com.blm.vo.PageVO;
import com.blm.vo.ReviewVO;
import com.blm.vo.StoreStatisticsVO;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 商家评价管理服务实现类
 */
@Service
public class MerchantReviewServiceImpl implements MerchantReviewService {

    @Autowired
    private ReviewRepository reviewRepository;
    
    @Autowired
    private StoreService storeService;

    @Autowired
    private UserService userService;


    @Override
    @Cacheable(value = CacheConstant.REVIEWS, key = "#storeId + '_' + #storeRating + '_' + #page + '_' + #size")
    public PageVO<ReviewVO> listStoreReviews(Long merchantId, Long storeId, Integer storeRating, int page, int size) {
        // 验证店铺所有权
        storeService.verifyStoreOwner(storeId, merchantId);
        
        // 使用PageHelper进行分页查询
        PageHelper.startPage(page, size);
        List<Review> reviews;
        if(storeRating == null){
            reviews = reviewRepository.findByStoreId(storeId);
        }else if(storeRating >= 1 && storeRating <= 5){
            reviews = reviewRepository.findByStoreIdAndRating(storeId, storeRating);
        }else{
            throw new CommonException(ExceptionConstant.REQ_PARAM_ERROR);
        }

        Page<Review> pageInfo = (Page<Review>) reviews;
        // 转换为VO列表，并填充用户信息
        List<ReviewVO> reviewVOs = reviews.stream().map(review -> {
            ReviewVO vo = new ReviewVO();
            BeanUtils.copyProperties(review, vo);

            // 填充用户信息
            try {
                User user = userService.findUserById(review.getUserId());
                vo.setUserName(user.getUsername());
                vo.setUserAvatar(user.getAvatar());
            } catch (Exception ignore) {}

            return vo;
        }).collect(Collectors.toList());

        // 构造分页结果
        return new PageVO<>(page, size, pageInfo.getTotal(), pageInfo.getPages(), reviewVOs);
    }
    
    @Override
    @Cacheable(value = CacheConstant.REVIEW_STAT, key = "#storeId")
    public StoreStatisticsVO.ReviewStatisticsVO getReviewStatistics(Long merchantId, Long storeId) {
        // 验证店铺所有权
        Store store = storeService.getStoreById(storeId);
                
        if (!store.getMerchantId().equals(merchantId)) {
            throw new CommonException(ExceptionConstant.STORE_UNAUTHORIZED);
        }
        
        StoreStatisticsVO.ReviewStatisticsVO statistics = new StoreStatisticsVO.ReviewStatisticsVO();
        statistics.setStoreId(storeId);
        statistics.setStoreName(store.getName());

        List<ReviewRepository.RatingAggregation> ratingAggregations = reviewRepository.aggregateRatingsByStoreId(storeId);

        int totalReviews = 0;
        double sumRating = 0.0;
        Map<Integer, Integer> ratingCounts = new HashMap<>();

        for (ReviewRepository.RatingAggregation aggregation : ratingAggregations) {
            Integer rating = aggregation.getRating();
            Long count = aggregation.getCount();
            totalReviews += count;
            sumRating += rating * count;

            // 统计各评分数量
            ratingCounts.put(rating, count.intValue());
        }

        statistics.setTotalReviews(totalReviews);
        statistics.setAverageRating(totalReviews > 0
                ? BigDecimal.valueOf(sumRating / totalReviews).setScale(2, RoundingMode.HALF_UP).doubleValue()
                : 0.0);
        statistics.setRatingCounts(ratingCounts);
        // 计算好评率：4-5星占比
        int goodReviews = ratingCounts.getOrDefault(4, 0) + ratingCounts.getOrDefault(5, 0);
        BigDecimal goodRate = totalReviews > 0
                ? BigDecimal.valueOf((double) goodReviews / totalReviews).setScale(2, RoundingMode.HALF_UP)
                : BigDecimal.ZERO;
        statistics.setGoodRatePercentage(goodRate.doubleValue());

        return statistics;
    }
}